﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using ProtoBuf;

namespace TCG
{
	[ProtoBuf.ProtoContract]
	public class PrefabRenderData
	{
		[ProtoBuf.ProtoMember (1)]
		public string transformPath { get; set; }

		[ProtoBuf.ProtoMember (2)]
		public IList<uint> sharedMatIds { get; set; }

		public IList<GameAsset<Material>> sharedMats 
		{ 
			get 
			{ 
				if (m_sharedMats == null)
				{
					m_sharedMats = new List<GameAsset<Material>> ();
					for (int i = 0; i < sharedMatIds.Count; ++ i)
					{
						m_sharedMats.Add (null);
					}
				}
				return m_sharedMats;
			}
		}

		public void TryMatrial (uint matId, GameAsset<Material> mat)
		{
			for (int i = 0, len = sharedMatIds.Count; i < len; ++ i)
			{
				if (sharedMatIds[i] == matId)
				{
					sharedMats[i] = mat;
				}
			}
		}

		public bool completed
		{
			get 
			{
				for (int i = 0, len = sharedMatIds.Count; i < len; ++ i)
				{
					if (sharedMats[i] == null)
					{
						return false;
					}
				}
				return true; 
			}
		}

		public void Unload ()
		{
			if (m_sharedMats != null)
			{
				for (int i = 0, len = m_sharedMats.Count; i < len; ++ i)
				{
					GameAsset<Material> mat = m_sharedMats[i];
					GameAssetsDatabase.instance.materialDatabase.ReleaseAsset (mat);
				}
			}
		}

		public override string ToString ()
		{
			return string.Format ("[PrefabRenderData: transformPath={0}, sharedMatIds={1}]", 
			                      transformPath, 
			                      CommonTools.JointCollection<uint> (sharedMatIds));
		}

		IList<GameAsset<Material>> m_sharedMats = null;
	}

	[ProtoBuf.ProtoContract]
	public class PrefabData
	{
		[ProtoBuf.ProtoMember (1)]
		public uint prefabId { get; set;}

		[ProtoBuf.ProtoMember (2)]
		public IList<PrefabRenderData> renderDatas { get; set; }

		public GameObject prefab { get; set;}

		public void MakePrefab ()
		{
			Transform trans = prefab.transform;
			for (int i = 0,len = renderDatas.Count; i < len; ++ i)
			{
				PrefabRenderData renderData =  renderDatas[i];
				Transform childTrans = trans.FindChild (renderData.transformPath);
				Material[] sharedMaterials = new Material[renderData.sharedMats.Count];
				for (int j = 0, matLen = sharedMaterials.Length; j < matLen; ++ j)
				{
					sharedMaterials[j] = renderData.sharedMats[j].asset;
				}
				childTrans.renderer.sharedMaterials = sharedMaterials;
			}
		}

		public void Unload ()
		{
			prefab = null;
			prefabId = 0;
			if (renderDatas != null)
			{
				for (int i = 0, len = renderDatas.Count; i < len; ++ i)
				{
					PrefabRenderData renderData = renderDatas[i];
					renderData.Unload ();
				}
			}
		}

		public override string ToString ()
		{
			return string.Format ("[PrefabData: prefabId={0}, renderDatas={1}]", 
			                      prefabId, 
			                      CommonTools.JointCollection<PrefabRenderData> (renderDatas));
		}

		public void Serialize (System.IO.Stream stream)
		{
			ProtoBuf.Serializer.Serialize<PrefabData> (stream, this);
			Debug.Log (this.ToString ());
		}
	}
}